/**
 * Project Name:fire-industry-DM-center
 * File Name:OSSUtil.java
 * Package Name:com.firestone.core.utils
 * Date:2018年3月15日下午5:11:57
 *
*/

package com.firestone.core.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.firestone.common.tool.GenUuid;
import com.firestone.common.tool.Md5Utils;

/**
 * @Description: TODO(阿里云OSS工具)
 * @author CAIYJ
 * @date 2018年3月15日 下午5:11:57
 */
@Component
public class OSSUtil {
    private static final Logger logger = LogManager.getLogger(OSSUtil.class);

    /**
     * @Fields ENDPOINT : TODO(阿里云API的内或外网域名)
     */
    @Value(value = "${spring.oss.endpoint}")
    private static String ENDPOINT;

    /**
     * @Fields ACCESS_KEY_ID : TODO(阿里云API的密钥Access Key ID)
     */
    @Value(value = "${spring.oss.access.key.id}")
    private static String ACCESS_KEY_ID;

    /**
     * @Fields ACCESS_KEY_SECRET : TODO(阿里云API的密钥Access Key Secret)
     */
    @Value(value = "${spring.oss.access.key.secret}")
    private static String ACCESS_KEY_SECRET;

    @Value(value = "${spring.oss.bucket.name}")
    private static String BUCKET_NAME;

    @Value(value = "${spring.oss.base.url}")
    private static String BASE_URL;

    public static String getENDPOINT() {
        return ENDPOINT;
    }

    public static void setENDPOINT(String eNDPOINT) {
        ENDPOINT = eNDPOINT;
    }

    public static String getACCESS_KEY_ID() {
        return ACCESS_KEY_ID;
    }

    public static void setACCESS_KEY_ID(String aCCESS_KEY_ID) {
        ACCESS_KEY_ID = aCCESS_KEY_ID;
    }

    public static String getACCESS_KEY_SECRET() {
        return ACCESS_KEY_SECRET;
    }

    public static void setACCESS_KEY_SECRET(String aCCESS_KEY_SECRET) {
        ACCESS_KEY_SECRET = aCCESS_KEY_SECRET;
    }

    public static String getBUCKET_NAME() {
        return BUCKET_NAME;
    }

    public static void setBUCKET_NAME(String bUCKET_NAME) {
        BUCKET_NAME = bUCKET_NAME;
    }

    public static String getBASE_URL() {
        return BASE_URL;
    }

    public static void setBASE_URL(String bASE_URL) {
        BASE_URL = bASE_URL;
    }

    public static void main(String[] args) {
        OSSClient client = OSSUtil.getOSSClient();
        try {
            BufferedInputStream bis = new BufferedInputStream(
                    OSSUtil.getOSS2InputStream(client, "rcboxtest", "",
                            "71fa2f1c2f33751076fc523bb089396b21cd1"));
            String resfile = "D:\\data\\oss\\71fa2f1c2f33751076fc523bb089396b21cd1.doc";
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(new File(resfile)));
            int itemp = 0;
            while ((itemp = bis.read()) != -1) {
                bos.write(itemp);
            }
            logger.info("文件获取成功"); // console log :文件获取成功
            bis.close();
            bos.close();
        } catch (Exception e) {
            logger.error("从OSS获取文件失败:" + e.getMessage(), e);
        }
    }

    /**
     * 向阿里云的OSS存储中存储文件 --file也可以用InputStream替代
     *
     * @param file
     *            上传文件
     * @return String 唯一MD5数字签名
     */
    public static final String uploadObject2OSS(MultipartFile file) {
        String resultStr = null;
        try {
            InputStream is = file.getInputStream();
            String fileName = file.getOriginalFilename();
            Long fileSize = file.getSize();
            String diskName = Md5Utils.toMD5(GenUuid.GetUuid());
            // 创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(is.available());
            metadata.setCacheControl("no-cache");
            metadata.setHeader("Pragma", "no-cache");
            metadata.setContentEncoding("utf-8");
            String fileExtension = file.getOriginalFilename()
                    .substring(fileName.lastIndexOf("."));
            metadata.setContentType(getContentType(fileExtension));
            String newFileName = diskName + fileExtension;
            metadata.setContentDisposition(
                    "filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            // 上传文件
            getOSSClient().putObject(BUCKET_NAME, newFileName, is, metadata);
            // 解));
            resultStr = BASE_URL + newFileName;
        } catch (Exception e) {
            logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }
        return resultStr;
    }

    /**
     * 获取阿里云OSS客户端对象
     */
    public static final OSSClient getOSSClient() {
        return new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
    }

    /**
     * 新建Bucket --Bucket权限:私有
     * 
     * @param bucketName
     *            bucket名称
     * @return true 新建Bucket成功
     */
    public static final boolean createBucket(OSSClient client,
            String bucketName) {
        Bucket bucket = client.createBucket(bucketName);
        return bucketName.equals(bucket.getName());
    }

    /**
     * 删除Bucket
     * 
     * @param bucketName
     *            bucket名称
     */
    public static final void deleteBucket(OSSClient client, String bucketName) {
        client.deleteBucket(bucketName);
        logger.info("删除" + bucketName + "Bucket成功");
    }

    /**
     * 向阿里云的OSS存储中存储文件 --file也可以用InputStream替代
     * 
     * @param client
     *            OSS客户端
     * @param file
     *            上传文件
     * @param bucketName
     *            bucket名称
     * @param diskName
     *            上传文件的目录 --bucket下文件的路径
     * @return String 唯一MD5数字签名
     */
    public static final String uploadObject2OSS(OSSClient client, File file,
            String bucketName, String diskName) {
        String resultStr = null;
        try {
            InputStream is = new FileInputStream(file);
            String fileName = file.getName();
            Long fileSize = file.length();
            // 创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(is.available());
            metadata.setCacheControl("no-cache");
            metadata.setHeader("Pragma", "no-cache");
            metadata.setContentEncoding("utf-8");
            metadata.setContentType(getContentType(fileName));
            metadata.setContentDisposition(
                    "filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            // 上传文件
            PutObjectResult putResult = client.putObject(bucketName,
                    diskName + fileName, is, metadata);
            // 解析结果
            resultStr = putResult.getETag();
        } catch (Exception e) {
            logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }
        return resultStr;
    }

    /**
     * 根据key获取OSS服务器上的文件输入流
     * 
     * @param client
     *            OSS客户端
     * @param bucketName
     *            bucket名称
     * @param diskName
     *            文件路径
     * @param key
     *            Bucket下的文件的路径名+文件名
     */
    public static final InputStream getOSS2InputStream(OSSClient client,
            String bucketName, String diskName, String key) {
        OSSObject ossObj = client.getObject(bucketName, diskName + key);
        return ossObj.getObjectContent();
    }

    /**
     * 根据key删除OSS服务器上的文件
     * 
     * @param client
     *            OSS客户端
     * @param bucketName
     *            bucket名称
     * @param diskName
     *            文件路径
     * @param key
     *            Bucket下的文件的路径名+文件名
     */
    public static void deleteFile(OSSClient client, String bucketName,
            String diskName, String key) {
        client.deleteObject(bucketName, diskName + key);
        logger.info("删除" + bucketName + "下的文件" + diskName + key + "成功");
    }

    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     * 
     * @param fileName
     *            文件名
     * @return 文件的contentType
     */
    public static final String getContentType(String fileName) {
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        if ("bmp".equalsIgnoreCase(fileExtension))
            return "image/bmp";
        if ("gif".equalsIgnoreCase(fileExtension))
            return "image/gif";
        if ("jpeg".equalsIgnoreCase(fileExtension)
                || "jpg".equalsIgnoreCase(fileExtension)
                || "png".equalsIgnoreCase(fileExtension))
            return "image/jpeg";
        if ("html".equalsIgnoreCase(fileExtension))
            return "text/html";
        if ("txt".equalsIgnoreCase(fileExtension))
            return "text/plain";
        if ("vsd".equalsIgnoreCase(fileExtension))
            return "application/vnd.visio";
        if ("ppt".equalsIgnoreCase(fileExtension)
                || "pptx".equalsIgnoreCase(fileExtension))
            return "application/vnd.ms-powerpoint";
        if ("doc".equalsIgnoreCase(fileExtension)
                || "docx".equalsIgnoreCase(fileExtension))
            return "application/msword";
        if ("xml".equalsIgnoreCase(fileExtension))
            return "text/xml";
        return "text/html";
    }

}
